﻿using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using Padsurface.CoreAudio.Common;
using Padsurface.CoreAudio.Components.WASAPI;
using Padsurface.CoreAudio.Components.WASAPI.Interfaces;
using Padsurface.CoreAudio.Constants;
using Padsurface.CoreAudio.Enumerations;
using Padsurface.CoreAudio.MultiMediaStructures;
using Padsurface.CoreAudio.Wrappers.Services;
using Padsurface.CoreAudio.Wrappers.Services.Interfaces;
using Padsurface.Tests;
using System;
using System.Runtime.InteropServices;
using System.Threading;

namespace Padsurface.CoreAudio.Tests.Integration.Wrappers.AudioCaptureClientActivatorSpecifications
{
    public abstract class WhenActivate : TestBase
    {
        protected IAudioCaptureClientActivator AudioCaptureClientActivator { get; private set; }
        protected IAudioClient AudioClient { get; set; }
        protected IAudioCaptureClient Result { get; private set; }

        protected override void Arrange()
        {
            AudioCaptureClientActivator = new AudioCaptureClientActivator();
        }

        protected override void Act()
        {
            Result = AudioCaptureClientActivator.Activate(AudioClient);
        }
    }

    [TestClass]
    public class WhenActivateGivenAudioClientIsEmpty : WhenActivate
    {
        protected override void Arrange()
        {
            base.Arrange();
            AudioClient = null;
        }

        protected override void Act()
        {
            ExpectException(base.Act);
        }

        [TestMethod]
        public void ThenAnArgumentNullExceptionShouldBeThrown()
        {
            Assert.IsNotNull(Exception);
            Assert.IsInstanceOfType(Exception, typeof(ArgumentNullException));
            Assert.AreEqual("audioClient", (Exception as ArgumentNullException).ParamName);
        }
    }

    [TestClass]
    public class WhenActivateGivenAudioClientNotInitialized : WhenActivate
    {
        protected override void Arrange()
        {
            base.Arrange();

            EventTrigger = new ManualResetEvent(false);           
            var audioClientActivator = new AudioClientActivator();
            audioClientActivator.Activate().ContinueWith(t => 
            {
                AudioClient = t.Result;
                EventTrigger.Set();
            });
            EventTrigger.WaitOne();
        }

        protected override void Act()
        {
            ExpectException(base.Act);
        }

        [TestMethod]
        public void ThenAnAudioClientNotInitializedExceptionShouldBeThrown()
        {
            Assert.IsNotNull(Exception);
            Assert.IsInstanceOfType(Exception, typeof(COMException));
            Assert.AreEqual(HResultCodes.AUDCLNT_E_NOT_INITIALIZED, (uint)(Exception as COMException).HResult);
        }
    }
}